#include "ndk_JNICopy.h"
#include "jni.h"
#include <exception>
#include <iostream>
#include <stdexcept>

using namespace std;

// 自定义异常，继承自动异常
class Excetion: public out_of_range{
private:
	char *msg;
public:
	Excetion(char *msg): out_of_range(msg)
	{
		this->msg = msg;
	}

	/*
	 * 异常说明：
 	 * 1.const throw() 不是函数，这个东西叫[异常规格说明]，表示 what 函数可以抛出异常的类型
	 * 2.类型说明放到 () 里 ，这里面没有类型，就是声明这个函数不抛出异常，通常函数不写后面的就表示函数可以抛出 任何类型的异常 。
	 * */
	const char * what() const throw()
	{
		return this->msg;
	}
};

void c_method()
{
	// C++ 中的异常可以是任意类型的
	//throw 1;
	throw Excetion((char *)"来自C++代码异常");
}

/*
 * Class:     ndk_JNICopy
 * Method:    arrayCopy
 * Signature: (Ljava/lang/Object;ILjava/lang/Object;II)V
 */
JNIEXPORT void JNICALL Java_ndk_JNICopy_arrayCopy
  (JNIEnv *env, jclass jclzz, jobject src, jint srcPos, jobject dest, jint destPos, jint len)
{

	jobjectArray array_src = static_cast<jobjectArray>(src);
	jobjectArray array_dest = static_cast<jobjectArray>(dest);
	if (array_src != NULL && array_dest != NULL) 
	{	
		cout << "类型转换成功" << endl;
		for (int i = srcPos; i < srcPos + len; i++) {
			// 原数组中取元素
			jobject srcObj = env->GetObjectArrayElement(array_src, i);
			// 放入目标数组
			env->SetObjectArrayElement(array_dest, i, srcObj);
		}
	}
	else {
		cout << "类型转换异常" << endl;
	}

	/*
	 * NDK异常总结：
	 * 1.C++中的代码需要进行try，在Java层try没有意义，Java层捕捉不到C++异常
	 * 2.C++中捕获到异常需要按照Java的方式抛给Java，让Java层知道
	 * 3.NDK代码中最好自定义自己的异常
	 *
	 * */
	
	try {
		c_method();
	} catch (const Excetion &e) {
		// 捕获到C++异常，抛给Java层
		jclass je = env->FindClass("java/lang/Exception");
		env->ThrowNew(je, e.what());	
	}


}
